<template>
  <el-container v-loading="loading" style="height: 100%;">

    <el-aside :width="menuRightCollapse ? 'auto' : '220px'" class="aside">
      <el-scrollbar>
        <el-menu
            active-text-color="#ffd04b"
            background-color="#545c64"
            text-color="#fff"
            class="el-menu-vertical-demo"
            :collapse="menuRightCollapse"
            :router="true"
            :default-active="routerPath"
        >
          <menu-tree v-model:menu-list="menuList"></menu-tree>
        </el-menu>
      </el-scrollbar>
    </el-aside>

    <el-container>

      <el-header style="height: auto">
        <div>
          <el-menu
              class="el-menu-demo"
              mode="horizontal"
              :ellipsis="false"
          >
            <el-menu-item index="0" @click="menuRightCollapse = !menuRightCollapse">
              <div>
                <el-icon>
                  <Fold v-show="!menuRightCollapse"/>
                  <Expand v-show="menuRightCollapse"/>
                </el-icon>
              </div>
            </el-menu-item>

            <div class="flex-grow flex-center">
              <div >
                {{route.meta.title}}
              </div>
            </div>
            <el-sub-menu index="1">
              <template #title>资源下载</template>
              <el-menu-item index="1-1" @click="generateQRCode" >APP下载</el-menu-item>
            </el-sub-menu>
            <el-sub-menu index="2">
              <template #title>
                <el-space wrap :size="10">
                  <el-avatar icon="UserFilled" shape="square" :size="35" :src="minioAdd + userInfo.avatar"/>
                  {{ userInfo.username }}
                </el-space>
              </template>
              <el-menu-item index="2-1" @click="toPersonal">个人信息</el-menu-item>
              <el-menu-item index="2-5" @click="onSubmit">退出登录</el-menu-item>
            </el-sub-menu>
            <el-menu-item index="3" >
              <el-switch
                  @click="toggleDark()"
                  v-model="switchFlag"
                  active-action-icon="Sunny"
                  inactive-action-icon="MoonNight"
                  :active-text="'明亮'"
                  :inactive-text="'暗黑'"
              />
            </el-menu-item>
          </el-menu>
          <div class="tags-box-scroll" ref="tagsBoxScrollBoxRef" @wheel="handleScroll">
            <el-scrollbar ref="tagsBoxScrollRef">
              <div class="tags-box" ref="tagsBoxRef">
                <div v-for="(item, index) in editableTabs" @click="tabClick(item)"
                     :class="item.name == editableTabsValue ? 'tag-box flex-center tag-box-active' : 'tag-box flex-center'">
                  <div class="tag-dian"></div>
                  <div class="tag-message">{{ item.title }}</div>
                  <el-icon v-if="item.name !== '/'" @click.stop="removeTab(item, index)" class="tag-coles">
                    <Close/>
                  </el-icon>
                </div>
              </div>
            </el-scrollbar>
          </div>
        </div>
      </el-header>

      <el-main>
        <router-view name="index" v-slot="{ Component }">
          <keep-alive ref="keepAliveRef" :include="includeList">
            <component :is="Component" :key="route.name" v-if="route.meta.keepalive" />
          </keep-alive>
          <component :is="Component" :key="route.name" v-if="!route.meta.keepalive" />
        </router-view>
      </el-main>

    </el-container>
  </el-container>

  <el-drawer
      v-model="drawer"
      title="APP下载"
      direction="ttb"
  >
    <el-row justify="space-around">
      <el-col justify="space-around">
        <el-row justify="space-around">
          <span><span style="color: #4b95f3;cursor: pointer; text-decoration: underline;" @click="downloadQrode">点击下载</span><span>或扫描二维码下载</span></span>
        </el-row>
      </el-col>
      <el-col justify="space-around">
        <el-row justify="space-around">
          <canvas ref="qrcodeCanvas"></canvas>
        </el-row>
      </el-col>
      <el-col justify="space-around">
        <el-row justify="space-around">
          {{appData.dictValue ? appData.dictValue : '暂无APP信息'}}
        </el-row>
      </el-col>
    </el-row>
  </el-drawer>
</template>

<script>
import {getCurrentInstance, onBeforeUnmount, onMounted, ref, watch} from "vue";
import {useRoute, useRouter} from "vue-router";
import {useDark, useToggle} from '@vueuse/core'

import QRCode from 'qrcode'
import userApi from "@/api/sys/user";
import menuApi from "@/api/sys/menu";
import menuTree from "@/views/sys/menu/menuTree";
import dictTypeApi from "@/api/sys/dictType";

import websocket from "@/utils/websocket";
import {ElScrollbar} from "element-plus";
import dictDataApi from "@/api/sys/dictData";
import {addDynamicRoutes} from "@/router";

export default {
  name: "index",
  props: [],
  emits: [],
  components: {menuTree},
  setup(props, content) {
    const router = useRouter()
    const route = useRoute()
    const {proxy} = getCurrentInstance();

    const tagsBoxScrollBoxRef = ref()
    const tagsBoxScrollRef = ref()
    const tagsBoxRef = ref()
    const keepAliveRef = ref()
    const qrcodeCanvas = ref()

    const isDark = useDark()
    const toggleDark = useToggle(isDark)
    let data = {
      routerPath: ref(router.currentRoute.value.path),
      userInfo: ref({
        username: "--"
      }),
      menuList: ref([]),
      menuRightCollapse: ref(false),
      loading: ref(false),
      editableTabsValue: ref(""),//打开的路由path
      includeList : ref([]),//历史打开路由name
      editableTabs: ref([]),//历史打开的路由对象
      tagScroll: ref(0),//历史打开的路由对象
      code: ref(106),
      drawer: ref(false),
      appData: ref({}),
      switchFlag: ref(false),
      minioAdd: ref(""),
    }
    //监听
    watch(() => route,(newVal,oldVal)=>{
      if(newVal.meta.keepalive && data.includeList.value.indexOf(newVal.name) === -1){
        data.includeList.value.push(newVal.name);
      }
      let val = {
        name : newVal.meta.title,
        path : newVal.path,
      }
      methods.menuClick(val)
    },{deep:true}) // 开启深度监听
    //监听
    watch(() => isDark,(newVal,oldVal)=>{
      if (data.switchFlag.value === newVal.value){
        data.switchFlag.value = !newVal.value
      }
    },{deep:true}) // 开启深度监听

    onMounted(async () => {

      data.switchFlag.value = !isDark.value
      await methods.loadInfo()
      //如果状态正常且未连接
      if (!websocket.isConnection() && data.code.value !== 106){
          await websocket.connectWebsocket()
      }
    })
    let methods = {
      async loadInfo() {
        data.loading.value = true
        await userApi.getUserInfo().then(res => {
          if (res.success) {
            data.userInfo.value = res.data
            data.code.value = res.code
            methods.getMenuAndDict();
          }
        },err => {
          console.log(err)
          router.push({
            path: '/login',
          })
        })

      },
      async getMenuAndDict() {
        await menuApi.getNav().then(resnav => {
          if (resnav.success) {
            data.menuList.value = resnav.data.nav
            sessionStorage.setItem('permission', resnav.data.authoritys)
            data.loading.value = false
            addDynamicRoutes(data.menuList.value); // 动态添加路由
            router.replace("/"); // 刷新页面，保证新路由生效
            //打开历史路由
            methods.routerLoad();
          }
        })
        await dictTypeApi.getTreeDict().then(resdict => {
          if (resdict.success) {
            sessionStorage.setItem('dictionaries', JSON.stringify(resdict.data))
          }
        })
        let res = proxy.$tools.selectDictSysConfig("minioAdd")
        data.minioAdd.value = res.remarks
      },
      routerLoad(){
        let rou = router.currentRoute.value
        setTimeout(function (){
          if(rou && rou.meta.keepalive && data.includeList.value.indexOf(rou.name) === -1){
            let val = {
              name : rou.meta.title,
              path : rou.path,
            }
            router.push(rou.path)
            methods.menuClick(val)
          }
        }, 500)

      },
      generateQRCode() {
        data.drawer.value = true

        dictDataApi.getDataByTypeOne('appVersion', '1').then(res => {
          qrcodeCanvas.value.getContext('2d').clearRect(0, 0, qrcodeCanvas.value.width, qrcodeCanvas.value.height);
          data.appData.value = res.data ? res.data : {}
              let dictKey =  data.appData.value ? data.appData.value.dictKey : ''
          if (dictKey){
            QRCode.toCanvas(qrcodeCanvas.value , dictKey, (error) => {
              if (error) console.error(error)
              console.log('二维码生成成功！')
            })
          }
        })

      },
      downloadQrode(){
        let dictKey =  data.appData.value ? data.appData.value.dictKey : ''
          if (dictKey){
          // 创建一个隐藏的 <a> 标签
          const a = document.createElement('a');
          a.style.display = 'none';
          a.href = dictKey;
          a.download = 'app.apk';

          // 将 <a> 标签添加到 DOM 中
          document.body.appendChild(a);

          // 触发点击事件
          a.click();

          // 清理
          document.body.removeChild(a);
        }
      },
      onSubmit() {
        websocket.closeWebSocket()
        userApi.logout()
      },
      toPersonal() {
        router.push({
          path: '/sys/user/personal',
        })
      },
      menuClick(e) {
        let fil = data.editableTabs.value.filter(f => {
          return f.name === e.path
        })
        if (fil && fil.length > 0) {
          data.editableTabsValue.value = e.path
        } else {
          data.editableTabs.value.push({
            title: e.name,
            name: e.path,
            content: e.path,
          })
          data.editableTabsValue.value = e.path
          setTimeout(() => {
            let scorWidth = tagsBoxScrollBoxRef.value.clientWidth
            let boxWidth = tagsBoxRef.value.clientWidth
            if (boxWidth > scorWidth){
              let tag = boxWidth - scorWidth
              data.tagScroll.value = tag
              tagsBoxScrollRef.value.setScrollLeft(tag)
            }
          }, 20)

        }

      },
      tabClick(tabsPaneContext) {
        data.editableTabsValue.value = tabsPaneContext.name
        data.routerPath.value = tabsPaneContext.name
        router.push({
          path: tabsPaneContext.name,
        })
      },
      handleScroll(event){
        const delta = Math.sign(event.deltaY); // 获取鼠标滚动方向，1表示向下滚动，-1表示向上滚动
        let scorWidth = tagsBoxScrollBoxRef.value.clientWidth
        let boxWidth = tagsBoxRef.value.clientWidth
        let tag = JSON.parse(JSON.stringify(data.tagScroll.value))
        if (boxWidth > scorWidth || tag !== 0){
          if (delta === 1){
            if (tag < (boxWidth - scorWidth)) {
                data.tagScroll.value = tag + 20
            }
          }else{
            if (tag > 0) {
              if (tag - 10 < 0){
                data.tagScroll.value = 0
              }else{
                  data.tagScroll.value = tag - 20
              }
            }
          }
          tagsBoxScrollRef.value.setScrollLeft(tag)
        }
      },
      removeTab(targetName, index) {
        let tags = data.editableTabs.value;
        let tagsName = data.includeList.value;

        if (targetName.name === '/'){
          //不让关闭首页
          return
        }
        //关掉的是当前打开的
        if (targetName.name === data.editableTabsValue.value){
          if (tags.length > 1){
            let i = index;
            if (index === 0){
              i = index + 1
              router.push({
                path: tags[i].name,
              })
            }else if (index === tags.length-1){
              i = index - 1
              router.push({
                path: tags[i].name,
              })
            }else {
              i = index - 1
              router.push({
                path: tags[i].name,
              })
            }

            data.editableTabsValue.value = tags[i].name
            data.routerPath.value = tags[i].name
          }else{
            router.push({
              path: "/",
            })
          }
        }
        //清除缓存
        const cachedInstances = keepAliveRef.value.cache;
        for (const key in cachedInstances) {
          const cachedInstance = cachedInstances[key].instance;
          if (cachedInstance && cachedInstance.$options.name === targetName.name) {
            cachedInstance.$destroy(); // 销毁指定组件实例，从而清除缓存
          }
        }
        tags.splice(index, 1)
        tagsName.splice(index, 1)
      },
    }
    onBeforeUnmount(() => {
      websocket.closeWebSocket()
    })

    return {
      router,
      route,
      proxy,
      keepAliveRef,
      tagsBoxScrollBoxRef,
      tagsBoxScrollRef,
      tagsBoxRef,
      qrcodeCanvas,
      isDark,
      toggleDark,
      ...data,
      ...methods
    }
  }
}
</script>

<style lang="scss" scoped>
.icon {
  width: 1em;
  height: 1em;
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;
  font-size: 3rem;
}
.flex-grow {
  flex-grow: 1;
  color: var(--el-menu-text-color);
}

.aside {
  .el-menu {
    height: 100vh;
  }
}

.el-main {
  --el-main-padding: .5rem 1rem;
  background-color: var(--el-bg-color);
}

.el-header {
  padding: 0;
  background-color: var(--el-bg-color);

  .tags-box-scroll{
    overflow: hidden;
    position: relative;
    white-space: nowrap;
    background-color: var(--el-bg-color);
    border-bottom: 1px solid var(--el-menu-border-color);
  }
  .tags-box{
    padding: .1rem;
    display: inline-flex;

    //white-space: nowrap;
    .tag-box{
      cursor: pointer;
      display: inline-flex;
      padding: .2rem 1rem;
      border-right: 1px solid var(--el-color-info);
      color: var(--el-menu-text-color);
      font-size: 14px;
      .tag-dian{
        width: .5rem;
        height: .5rem;
        border-radius: 1rem;
        background-color: #DDDDDDFF;
      }
      .tag-message{
        margin-left: .5rem;
        font-size: 0.8rem;
      }
      .tag-coles{
        display: none;
        border-radius: 1rem;
        margin: .1rem 0 0 .5rem;
        &:hover{
          color: #FFFFFF;
          background-color: #a8abb2;
        }
      }

      &:hover{
        color: #4d70ff;
        .tag-dian{
          background-color: #4d70ff;
        }
        .tag-coles{
          display: inline-flex;
        }
      }
    }
    .tag-box-active{
      background-color: rgba(64,158,255,.08);
      color: #4d70ff;
      .tag-dian{
        background-color: #4d70ff;
      }
      .tag-coles{
        display: inline-flex;
      }
      @extend .tag-box
    }
  }
}

.el-menu-demo{
  .el-sub-menu .el-icon{
    font-size: 4rem;
    margin-right: 0 !important;
  }
}
</style>